package me.moodcat.api.filters;
import java.io.IOException;
import javax.ws.rs.NotAuthorizedException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import me.moodcat.backend.UserBackend;
import me.moodcat.core.mappers.NotAuthorizedExceptionMapper;
import me.moodcat.database.entities.User;
import com.google.common.base.Strings;
import com.google.inject.Inject;
import com.google.inject.Key;
import com.google.inject.name.Names;
/**
* The {@code AuthorizationFilter} ensures that a current user can be injected
* in the current request scope, given that the request provides a SoundCloud
* OAuth token through its query parameters and the token can be verified against
* the SoundCloud services.
*/
@Provider
@PreMatching
public class AuthorizationFilter implements ContainerRequestFilter {
protected static final String TOKEN_PARAMETER = "token";
private static final String CURRENT_USER_NAME = "current.user";
private final UserBackend userBackend;
private final NotAuthorizedExceptionMapper notAuthorizedExceptionMapper;
@Inject
public AuthorizationFilter(final UserBackend userBackend,
final NotAuthorizedExceptionMapper notAuthorizedExceptionMapper) {
this.userBackend = userBackend;
this.notAuthorizedExceptionMapper = notAuthorizedExceptionMapper;
}
@Override
public void filter(final ContainerRequestContext containerRequestContext) throws IOException {
final MultivaluedMap<String, String> parameters = containerRequestContext.getUriInfo()
.getQueryParameters();
final String token = parameters.getFirst(TOKEN_PARAMETER);
if (!Strings.isNullOrEmpty(token)) {
try {
final User user = userBackend.loginUsingSoundCloud(token);
containerRequestContext.setProperty(
Key.get(User.class, Names.named(CURRENT_USER_NAME))
.toString(), user);
} catch (final NotAuthorizedException e) {
final Response response = notAuthorizedExceptionMapper.toResponse(e);
containerRequestContext.abortWith(response);
}
}
}
}